OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 15028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15039 | 15039 |
15040 Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); | 15040 Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); |
15041 CHECK(result5->Equals( | 15041 CHECK(result5->Equals( |
15042 object_with_hidden->GetPrototype()->ToObject()->GetPrototype())); | 15042 object_with_hidden->GetPrototype()->ToObject()->GetPrototype())); |
15043 | 15043 |
15044 Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); | 15044 Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); |
15045 CHECK(result6->Equals(Undefined())); | 15045 CHECK(result6->Equals(Undefined())); |
15046 | 15046 |
15047 context.Dispose(); | 15047 context.Dispose(); |
15048 } | 15048 } |
| 15049 |
| 15050 |
| 15051 static void TestReceiver(Local<Value> expected_result, |
| 15052 Local<Value> expected_receiver, |
| 15053 const char* code) { |
| 15054 Local<Value> result = CompileRun(code); |
| 15055 CHECK(result->IsObject()); |
| 15056 CHECK(expected_receiver->Equals(result->ToObject()->Get(1))); |
| 15057 CHECK(expected_result->Equals(result->ToObject()->Get(0))); |
| 15058 } |
| 15059 |
| 15060 |
| 15061 THREADED_TEST(ForeignFunctionReceiver) { |
| 15062 HandleScope scope; |
| 15063 |
| 15064 // Create two contexts with different "id" properties ('i' and 'o'). |
| 15065 // Call a function both from its own context and from a the foreign |
| 15066 // context, and see what "this" is bound to (returning both "this" |
| 15067 // and "this.id" for comparison). |
| 15068 |
| 15069 Persistent<Context> foreign_context = v8::Context::New(); |
| 15070 foreign_context->Enter(); |
| 15071 Local<Value> foreign_function = |
| 15072 CompileRun("function func() { return { 0: this.id, " |
| 15073 " 1: this, " |
| 15074 " toString: function() { " |
| 15075 " return this[0];" |
| 15076 " }" |
| 15077 " };" |
| 15078 "}" |
| 15079 "var id = 'i';" |
| 15080 "func;"); |
| 15081 CHECK(foreign_function->IsFunction()); |
| 15082 foreign_context->Exit(); |
| 15083 |
| 15084 LocalContext context; |
| 15085 |
| 15086 Local<String> password = v8_str("Password"); |
| 15087 // Don't get hit by security checks when accessing foreign_context's |
| 15088 // global receiver (aka. global proxy). |
| 15089 context->SetSecurityToken(password); |
| 15090 foreign_context->SetSecurityToken(password); |
| 15091 |
| 15092 Local<String> i = v8_str("i"); |
| 15093 Local<String> o = v8_str("o"); |
| 15094 Local<String> id = v8_str("id"); |
| 15095 |
| 15096 CompileRun("function ownfunc() { return { 0: this.id, " |
| 15097 " 1: this, " |
| 15098 " toString: function() { " |
| 15099 " return this[0];" |
| 15100 " }" |
| 15101 " };" |
| 15102 "}" |
| 15103 "var id = 'o';" |
| 15104 "ownfunc"); |
| 15105 context->Global()->Set(v8_str("func"), foreign_function); |
| 15106 |
| 15107 // Sanity check the contexts. |
| 15108 CHECK(i->Equals(foreign_context->Global()->Get(id))); |
| 15109 CHECK(o->Equals(context->Global()->Get(id))); |
| 15110 |
| 15111 // Checking local function's receiver. |
| 15112 // Calling function using its call/apply methods. |
| 15113 TestReceiver(o, context->Global(), "ownfunc.call()"); |
| 15114 TestReceiver(o, context->Global(), "ownfunc.apply()"); |
| 15115 // Making calls through built-in functions. |
| 15116 TestReceiver(o, context->Global(), "[1].map(ownfunc)[0]"); |
| 15117 CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/,ownfunc)[1]"))); |
| 15118 CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/g,ownfunc)[1]"))); |
| 15119 CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/g,ownfunc)[3]"))); |
| 15120 // Calling with environment record as base. |
| 15121 TestReceiver(o, context->Global(), "ownfunc()"); |
| 15122 // Calling with no base. |
| 15123 TestReceiver(o, context->Global(), "(1,ownfunc)()"); |
| 15124 |
| 15125 // Checking foreign function return value. |
| 15126 // Calling function using its call/apply methods. |
| 15127 TestReceiver(i, foreign_context->Global(), "func.call()"); |
| 15128 TestReceiver(i, foreign_context->Global(), "func.apply()"); |
| 15129 // Calling function using another context's call/apply methods. |
| 15130 TestReceiver(i, foreign_context->Global(), |
| 15131 "Function.prototype.call.call(func)"); |
| 15132 TestReceiver(i, foreign_context->Global(), |
| 15133 "Function.prototype.call.apply(func)"); |
| 15134 TestReceiver(i, foreign_context->Global(), |
| 15135 "Function.prototype.apply.call(func)"); |
| 15136 TestReceiver(i, foreign_context->Global(), |
| 15137 "Function.prototype.apply.apply(func)"); |
| 15138 // Making calls through built-in functions. |
| 15139 TestReceiver(i, foreign_context->Global(), "[1].map(func)[0]"); |
| 15140 // ToString(func()) is func()[0], i.e., the returned this.id. |
| 15141 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/,func)[1]"))); |
| 15142 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[1]"))); |
| 15143 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
| 15144 |
| 15145 // TODO(1547): Make the following also return "i". |
| 15146 // Calling with environment record as base. |
| 15147 TestReceiver(o, context->Global(), "func()"); |
| 15148 // Calling with no base. |
| 15149 TestReceiver(o, context->Global(), "(1,func)()"); |
| 15150 |
| 15151 foreign_context.Dispose(); |
| 15152 } |
OLD | NEW |