Revision: 3943
Author: [email protected]
Date: Wed Feb 24 11:59:09 2010
Log: Implement BlindReference object and provide couple of liveedit-specific structures

Review URL: http://codereview.chromium.org/650127
http://code.google.com/p/v8/source/detail?r=3943

Modified:
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/contexts.h
 /branches/bleeding_edge/src/liveedit.cc

=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Thu Feb 18 07:10:35 2010
+++ /branches/bleeding_edge/src/bootstrapper.cc Wed Feb 24 11:59:09 2010
@@ -1050,6 +1050,19 @@
     script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
     global_context()->set_empty_script(*script);
   }
+  {
+    // Builtin function for OpaqueReference -- a JSValue-based object,
+    // that keeps its field isolated from JavaScript code. It may store
+    // objects, that JavaScript code may not access.
+    Handle<JSFunction> opaque_reference_fun =
+        InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
+                        JSValue::kSize, Top::initial_object_prototype(),
+                        Builtins::Illegal, false);
+    Handle<JSObject> prototype =
+        Factory::NewJSObject(Top::object_function(), TENURED);
+    SetPrototype(opaque_reference_fun, prototype);
+    global_context()->set_opaque_reference_function(*opaque_reference_fun);
+  }

   if (FLAG_natives_file == NULL) {
     // Without natives file, install default natives.
=======================================
--- /branches/bleeding_edge/src/contexts.h      Tue Feb 16 01:24:14 2010
+++ /branches/bleeding_edge/src/contexts.h      Wed Feb 24 11:59:09 2010
@@ -95,6 +95,7 @@
     call_as_constructor_delegate) \
   V(EMPTY_SCRIPT_INDEX, Script, empty_script) \
   V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
+ V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function) \ V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
   V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \
   V(MAP_CACHE_INDEX, Object, map_cache) \
@@ -216,6 +217,7 @@
     CALL_AS_CONSTRUCTOR_DELEGATE_INDEX,
     EMPTY_SCRIPT_INDEX,
     SCRIPT_FUNCTION_INDEX,
+    OPAQUE_REFERENCE_FUNCTION_INDEX,
     CONTEXT_EXTENSION_FUNCTION_INDEX,
     OUT_OF_MEMORY_INDEX,
     MAP_CACHE_INDEX,
=======================================
--- /branches/bleeding_edge/src/liveedit.cc     Wed Feb 17 12:57:05 2010
+++ /branches/bleeding_edge/src/liveedit.cc     Wed Feb 24 11:59:09 2010
@@ -83,5 +83,144 @@
 bool LiveEditFunctionTracker::IsActive() {
   return active_function_info_listener != NULL;
 }
+
+// Unwraps JSValue object, returning its field "value"
+static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) {
+  return Handle<Object>(jsValue->value());
+}
+
+// Wraps any object into a OpaqueReference, that will hide the object
+// from JavaScript.
+static Handle<JSValue> WrapInJSValue(Object* object) {
+  Handle<JSFunction> constructor = Top::opaque_reference_function();
+  Handle<JSValue> result =
+      Handle<JSValue>::cast(Factory::NewJSObject(constructor));
+  result->set_value(object);
+  return result;
+}
+
+// Simple helper class that creates more or less typed structures over
+// JSArray object. This is an adhoc method of passing structures from C++
+// to JavaScript.
+template<typename S>
+class JSArrayBasedStruct {
+ public:
+  static S Create() {
+    Handle<JSArray> array = Factory::NewJSArray(S::kSize_);
+    return S(array);
+  }
+  static S cast(Object* object) {
+    JSArray* array = JSArray::cast(object);
+    Handle<JSArray> array_handle(array);
+    return S(array_handle);
+  }
+  explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) {
+  }
+  Handle<JSArray> GetJSArray() {
+    return array_;
+  }
+ protected:
+  void SetField(int field_position, Handle<Object> value) {
+    SetElement(array_, field_position, value);
+  }
+  void SetSmiValueField(int field_position, int value) {
+    SetElement(array_, field_position, Handle<Smi>(Smi::FromInt(value)));
+  }
+  Object* GetField(int field_position) {
+    return array_->GetElement(field_position);
+  }
+  int GetSmiValueField(int field_position) {
+    Object* res = GetField(field_position);
+    return Smi::cast(res)->value();
+  }
+ private:
+  Handle<JSArray> array_;
+};
+
+
+// Represents some function compilation details. This structure will be used
+// from JavaScript. It contains Code object, which is kept wrapped
+// into a BlindReference for sanitizing reasons.
+class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
+ public:
+  explicit FunctionInfoWrapper(Handle<JSArray> array)
+      : JSArrayBasedStruct<FunctionInfoWrapper>(array) {
+  }
+  void SetInitialProperties(Handle<String> name, int start_position,
+ int end_position, int param_num, int parent_index) {
+    HandleScope scope;
+    this->SetField(kFunctionNameOffset_, name);
+    this->SetSmiValueField(kStartPositionOffset_, start_position);
+    this->SetSmiValueField(kEndPositionOffset_, end_position);
+    this->SetSmiValueField(kParamNumOffset_, param_num);
+    this->SetSmiValueField(kParentIndexOffset_, parent_index);
+  }
+  void SetFunctionCode(Handle<Code> function_code) {
+    Handle<JSValue> wrapper = WrapInJSValue(*function_code);
+    this->SetField(kCodeOffset_, wrapper);
+  }
+  void SetScopeInfo(Handle<JSArray> scope_info_array) {
+    this->SetField(kScopeInfoOffset_, scope_info_array);
+  }
+  int GetParentIndex() {
+    return this->GetSmiValueField(kParentIndexOffset_);
+  }
+  Handle<Code> GetFunctionCode() {
+    Handle<Object> raw_result = UnwrapJSValue(Handle<JSValue>(
+        JSValue::cast(this->GetField(kCodeOffset_))));
+    return Handle<Code>::cast(raw_result);
+  }
+  int GetStartPosition() {
+    return this->GetSmiValueField(kStartPositionOffset_);
+  }
+  int GetEndPosition() {
+    return this->GetSmiValueField(kEndPositionOffset_);
+  }
+
+ private:
+  static const int kFunctionNameOffset_ = 0;
+  static const int kStartPositionOffset_ = 1;
+  static const int kEndPositionOffset_ = 2;
+  static const int kParamNumOffset_ = 3;
+  static const int kCodeOffset_ = 4;
+  static const int kScopeInfoOffset_ = 5;
+  static const int kParentIndexOffset_ = 6;
+  static const int kSize_ = 7;
+};
+
+// Wraps SharedFunctionInfo along with some of its fields for passing it
+// back to JavaScript. SharedFunctionInfo object itself is additionally
+// wrapped into BlindReference for sanitizing reasons.
+class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> {
+ public:
+  explicit SharedInfoWrapper(Handle<JSArray> array)
+      : JSArrayBasedStruct<SharedInfoWrapper>(array) {
+  }
+
+ void SetProperties(Handle<String> name, int start_position, int end_position,
+                     Handle<SharedFunctionInfo> info) {
+    HandleScope scope;
+    this->SetField(kFunctionNameOffset_, name);
+    Handle<JSValue> info_holder = WrapInJSValue(*info);
+    this->SetField(kSharedInfoOffset_, info_holder);
+    this->SetSmiValueField(kStartPositionOffset_, start_position);
+    this->SetSmiValueField(kEndPositionOffset_, end_position);
+  }
+  Handle<SharedFunctionInfo> GetInfo() {
+    Object* element = this->GetField(kSharedInfoOffset_);
+    Handle<JSValue> value_wrapper(JSValue::cast(element));
+    Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
+    return Handle<SharedFunctionInfo>::cast(raw_result);
+  }
+
+ private:
+  static const int kFunctionNameOffset_ = 0;
+  static const int kStartPositionOffset_ = 1;
+  static const int kEndPositionOffset_ = 2;
+  static const int kSharedInfoOffset_ = 3;
+  static const int kSize_ = 4;
+};
+
+

 } }  // namespace v8::internal

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to